Option Strict Off
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.IO
Imports System.Diagnostics
Imports System.Threading



Public Class AIRbasedRegistration
    Dim ofd1 As New OpenFileDialog
    Dim sfd As New SaveFileDialog


    Private Sub AIRbasedRegistration_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ofd1.Filter = "Analyze Header file (*.hdr)|*.hdr|All files (*.*)|*.*"
        ofd1.Title = "Choose the file"
        sfd.Filter = "Analyze Header file (*.hdr)|*.hdr|All files (*.*)|*.*"
        sfd.Title = "File Save as"
      
        ComboBox1.SelectedIndex = 0
        ComboBox2.SelectedIndex = 0
        ComboBox3.SelectedIndex = 0
        ComboBox4.SelectedIndex = 0
        ComboBox5.SelectedIndex = 0
    End Sub  
  
    Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
        Me.NumericUpDown1.Enabled = CheckBox1.Checked
        Me.NumericUpDown2.Enabled = CheckBox1.Checked
        Me.NumericUpDown3.Enabled = CheckBox1.Checked
    End Sub

    Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
        Me.NumericUpDown4.Enabled = CheckBox2.Checked
        Me.NumericUpDown5.Enabled = CheckBox2.Checked
        Me.NumericUpDown6.Enabled = CheckBox2.Checked
    End Sub

    Private Sub CheckBox8_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox8.CheckedChanged
        Me.NumericUpDown14.Enabled = CheckBox8.Checked
        Me.NumericUpDown15.Enabled = CheckBox8.Checked
        Me.NumericUpDown16.Enabled = CheckBox8.Checked
    End Sub

    Private Sub CheckBox7_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox7.CheckedChanged
        Me.NumericUpDown11.Enabled = CheckBox7.Checked
        Me.NumericUpDown12.Enabled = CheckBox7.Checked
        Me.NumericUpDown13.Enabled = CheckBox7.Checked

    End Sub

    Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
        NumericUpDown8.Enabled = CheckBox3.Checked
    End Sub

    Private Sub CheckBox4_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox4.CheckedChanged
        NumericUpDown7.Enabled = CheckBox4.Checked
    End Sub

    Private Sub CheckBox6_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox6.CheckedChanged
        Me.NumericUpDown9.Enabled = CheckBox6.Checked
    End Sub

    Private Sub CheckBox5_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox5.CheckedChanged
        Me.NumericUpDown10.Enabled = CheckBox5.Checked
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If ofd1.ShowDialog = Windows.Forms.DialogResult.OK Then
            TextBox1.Text = ofd1.FileName
        End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If ofd1.ShowDialog = Windows.Forms.DialogResult.OK Then
            TextBox2.Text = ofd1.FileName
        End If
    End Sub
    Dim tempfilename As String
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim ex As New ShellClass

        tempfilename = System.IO.Path.GetTempFileName
        Dim command As String = Chr(34) & My.Application.Info.DirectoryPath & "\"
        Dim command2 As String = command
        If TabControl1.SelectedIndex = 0 Then
            If ComboBox1.SelectedItem Is Nothing Or ComboBox3.SelectedItem Is Nothing Then Exit Sub
            command += "alignlinear.exe" & Chr(34) & " "
            command += Chr(34) & TextBox1.Text & Chr(34) & " " & Chr(34) & TextBox2.Text & Chr(34) & " " & Chr(34) & tempfilename & Chr(34) & " -m " & CInt(ComboBox1.SelectedItem.ToString.Substring(0, 2)) & " -v "
            If CheckBox1.Checked Then command += "-b1 " & NumericUpDown1.Value & " " & NumericUpDown2.Value & " " & NumericUpDown3.Value & " "
            If CheckBox2.Checked Then command += "-b2 " & NumericUpDown6.Value & " " & NumericUpDown5.Value & " " & NumericUpDown4.Value & " "
            If CheckBox3.Checked Then command += "-c " & NumericUpDown8.Value & " "
            If CheckBox4.Checked Then command += "-r " & NumericUpDown7.Value & " "
            command += "-x " & CInt(ComboBox3.SelectedItem.ToString.Substring(0, 1)) & " "
            If CheckBox9.Checked Then command += "-z"
            command2 += "scanair.exe" & Chr(34) & " " & Chr(34) & tempfilename & Chr(34)
        ElseIf TabControl1.SelectedIndex = 1 Then
            If ComboBox2.SelectedItem Is Nothing Then Exit Sub
            command += "align_warp.exe" & Chr(34) & " "
            command += Chr(34) & TextBox1.Text & Chr(34) & " " & Chr(34) & TextBox2.Text & Chr(34) & " " & Chr(34) & tempfilename & Chr(34) & " -m " & CInt(ComboBox2.SelectedItem.ToString.Substring(0, 2)) & " -v "
            If CheckBox8.Checked Then command += "-b1 " & NumericUpDown16.Value & " " & NumericUpDown15.Value & " " & NumericUpDown14.Value & " "
            If CheckBox7.Checked Then command += "-b2 " & NumericUpDown13.Value & " " & NumericUpDown12.Value & " " & NumericUpDown11.Value & " "
            If CheckBox6.Checked Then command += "-c " & NumericUpDown9.Value & " "
            If CheckBox5.Checked Then command += "-r " & NumericUpDown10.Value & " "
            command2 += "scan_warp.exe" & Chr(34) & " " & Chr(34) & tempfilename & Chr(34)
        End If

        logbox.Text += command & vbNewLine
        logbox.Select(logbox.Text.Length, 0)
        logbox.ScrollToCaret()

        ex.CaptureOutput = True
        ex.CaptureError = True
        ex.Execute(command)
        logbox.Text += vbNewLine
        logbox.Text += ex.Output & vbNewLine & vbNewLine

        Button4.Enabled = True

        logbox.Text += command2 & vbNewLine
        ex.Execute(command2)
        logbox.Text += ex.Output & vbNewLine & vbNewLine

        logbox.Select(logbox.Text.Length, 0)
        logbox.ScrollToCaret()
    End Sub

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        If sfd.ShowDialog <> Windows.Forms.DialogResult.OK Then Exit Sub
        Dim ex As New ShellClass
        Dim command As String = Chr(34) & My.Application.Info.DirectoryPath & "\"

        If TabControl1.SelectedIndex = 0 Then
            If ComboBox4.SelectedItem Is Nothing Then Exit Sub
            command += "reslice.exe" & Chr(34) & " "
            command += Chr(34) & tempfilename & Chr(34) & " "
            command += Chr(34) & sfd.FileName & Chr(34) & " -k -o -n " & CInt(ComboBox4.SelectedItem.ToString.Substring(0, 2))

        ElseIf TabControl1.SelectedIndex = 1 Then
            If ComboBox5.SelectedItem Is Nothing Then Exit Sub
            command += "reslice_warp.exe" & Chr(34) & " "
            command += Chr(34) & tempfilename & Chr(34) & " "

            command += Chr(34) & sfd.FileName & Chr(34) & " -o -n " & CInt(ComboBox5.SelectedItem.ToString.Substring(0, 1)) & " "
        End If
        logbox.Text += command & vbNewLine
        logbox.Select(logbox.Text.Length, 0)
        logbox.ScrollToCaret()

        ex.CaptureOutput = True
        ex.CaptureError = True
        ex.Execute(command)
        logbox.Text += vbNewLine
        logbox.Text += ex.Output & vbNewLine
        logbox.SelectionStart = logbox.Text.Length
        logbox.Text += "Saved to :" & Chr(34) & sfd.FileName & Chr(34) & vbNewLine & vbNewLine
        logbox.Select(logbox.Text.Length, 0)
        logbox.ScrollToCaret()
        Button5.Enabled = True
        If MsgBox("Open registered dataset?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
            FormMain.AnatomyVolume = CommonNamespace.HdrImgReader.ReadFromHdrFile(sfd.FileName, CommonNamespace.OutPutType.int16)
            FormMain.AnatomyDisplay.OpenFile(FormMain.AnatomyVolume, "Registered Anatomy", True, False)
        End If

    End Sub

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        If ofd1.ShowDialog <> Windows.Forms.DialogResult.OK Then Exit Sub
        Dim ex As New ShellClass
        Dim command As String = Chr(34) & My.Application.Info.DirectoryPath & "\"

        If TabControl1.SelectedIndex = 0 Then
            If ComboBox4.SelectedItem Is Nothing Then Exit Sub
            command += "mv_air.exe" & Chr(34) & " "
            command += Chr(34) & tempfilename & Chr(34) & " "
            command += Chr(34) & ofd1.FileName & Chr(34)

        ElseIf TabControl1.SelectedIndex = 1 Then
            If ComboBox5.SelectedItem Is Nothing Then Exit Sub
            command += "mv_warp.exe" & Chr(34) & " "
            command += Chr(34) & tempfilename & Chr(34) & " "
            command += Chr(34) & ofd1.FileName & Chr(34)

        End If

        logbox.Text += command & vbNewLine
        logbox.Select(logbox.Text.Length, 0)
        logbox.ScrollToCaret()

        ex.CaptureOutput = True
        ex.CaptureError = True
        ex.Execute(command)
        logbox.Text += vbNewLine
        logbox.Text += ex.Output & vbNewLine
        logbox.SelectionStart = logbox.Text.Length
        logbox.Text += "Changed to :" & Chr(34) & ofd1.FileName & Chr(34) & vbNewLine & vbNewLine
        logbox.Select(logbox.Text.Length, 0)
        logbox.ScrollToCaret()

    End Sub
End Class

''' <summary> 
''' Execute a command line string and return the <b style="color: black; background-color: rgb(153, 255, 153);">output</b> and/or error. 
''' </summary> 
Public Class ShellClass
    Implements IDisposable

    Private _p As Process
    Private _intMaxWaitMs As Integer = 120000
    Private _blnDisposed As Boolean = False
    Private _OutputBuilder As StringBuilder
    Private _ErrorBuilder As StringBuilder
    Private _blnGetOutput As Boolean = True
    Private _blnGetError As Boolean = True
    Private _blnLaunchInThread As Boolean = False
    Private _strWorkingDirectory As String
    Private _StartTime As DateTime
    Private _blnCancelRequested As Boolean = False
    Private Const _intSleepMs As Integer = 200
    Private _OutputThread As Thread
    Private _ErrorThread As Thread
    Private _blnProcessLaunched As Boolean = False

    Public Event OutputLine(ByVal LineText As String)
    Public Event ExecutionComplete(ByVal TimedOut As Boolean)

    ''' <summary> 
    ''' The working directory to be used by the process that is launched. 
    ''' If left blank, will default to the whatever the current path is. 
    ''' </summary> 
    Public Property WorkingDirectory() As String
        Get
            Return (_strWorkingDirectory)
        End Get
        Set(ByVal Value As String)
            _strWorkingDirectory = Value
        End Set
    End Property

    ''' <summary> 
    ''' <b style="color: black; background-color: rgb(255, 255, 102);">capture</b> any returned <b style="color: black; background-color: rgb(153, 255, 153);">output</b> from the command into the .<b style="color: black; background-color: rgb(153, 255, 153);">Output</b> string 
    ''' </summary> 
    Public Property CaptureOutput() As Boolean
        Get
            Return _blnGetOutput
        End Get
        Set(ByVal Value As Boolean)
            _blnGetOutput = Value
        End Set
    End Property

    ''' <summary> 
    ''' <b style="color: black; background-color: rgb(255, 255, 102);">capture</b> any returned errors from the command into the .Error string 
    ''' </summary> 
    Public Property CaptureError() As Boolean
        Get
            Return _blnGetError
        End Get
        Set(ByVal Value As Boolean)
            _blnGetError = Value
        End Set
    End Property

    ''' <summary> 
    ''' Maximum number of seconds to wait for the process to finish running.  
    ''' Use Integer.MaxValue to specify infinite wait. 
    ''' If the process is not finished in this time, it will be automatically killed. 
    ''' </summary> 
    Public Property MaximumWaitSeconds() As Integer
        Get
            Return Convert.ToInt32(_intMaxWaitMs / 1000)
        End Get
        Set(ByVal Value As Integer)
            _intMaxWaitMs = Value * 1000
        End Set
    End Property

    ''' <summary> 
    ''' execute the command in a seperate thread, synchronously; if not set, execution is asynchronous (blocking) 
    ''' </summary> 
    Public Property UseNewThread() As Boolean
        Get
            Return _blnLaunchInThread
        End Get
        Set(ByVal Value As Boolean)
            : _blnLaunchInThread = Value
        End Set
    End Property

    ''' <summary> 
    ''' any returned <b style="color: black; background-color: rgb(153, 255, 153);">output</b> from the command. Only provided if .CaptureOutput is True. 
    ''' </summary> 
    Public ReadOnly Property Output() As String
        Get
            If _OutputBuilder Is Nothing Then
                Return ""
            Else
                Return _OutputBuilder.ToString
            End If
        End Get
    End Property

    ''' <summary> 
    ''' any returned errors from the command. Only provided if .CaptureError is True. 
    ''' </summary> 
    Public ReadOnly Property [Error]() As String
        Get
            If _ErrorBuilder Is Nothing Then
                Return ""
            Else
                Return _ErrorBuilder.ToString
            End If
        End Get
    End Property

    ''' <summary> 
    ''' command execution time in milliseconds. Returns zero until execution is complete. 
    ''' </summary> 
    Public ReadOnly Property ExecutionTime() As Integer
        Get
            If _p Is Nothing Then Return 0
            If Not ProcessHasExited() Then Return 0
            Return Convert.ToInt32(New TimeSpan(_p.ExitTime.Ticks - _StartTime.Ticks).TotalMilliseconds)
        End Get
    End Property

    ''' <summary> 
    ''' exit code for the command. Returns -1 until execution is complete. 
    ''' </summary> 
    ''' <remarks> 
    ''' Developers usually indicate a successful exit by an ExitCode value of zero, and designate errors by nonzero  
    ''' values that the calling method can use to identify the cause of an abnormal process termination.  
    ''' It is not necessary to follow these guidelines, but they are the convention. 
    ''' </remarks> 
    Public ReadOnly Property ExitCode() As Integer
        Get
            If _p Is Nothing Then Return -1
            If Not ProcessHasExited() Then Return -1
            Return _p.ExitCode
        End Get
    End Property
    ''' <summary> 
    ' Executes a command line and waits for it to finish. Check .Error and .<b style="color: black; background-color: rgb(153, 255, 153);">Output</b> for results. 
    ''' Set .WorkingDirectory if your command is not fully pathed, or not in the path on this machine. 
    ''' </summary> 
    ''' <param name="Command">valid command line string to execute</param> 
    Public Sub Execute(ByVal Command As String)
        StartProcess("cmd.exe", "/c """ & Command & """")
    End Sub

    ''' <summary> 
    ''' Cancels execution of the command if it is still running 
    ''' </summary> 
    Public Sub CancelExecution()
        _blnCancelRequested = True
    End Sub

    Private Function ProcessHasExited() As Boolean
        If _p Is Nothing Then
            Return True
        End If
        Return _p.HasExited
    End Function

    Private Sub LaunchThreadHandler()
        '-- launch process 
        _p.Start()
        _blnProcessLaunched = True
        WaitForExit()
    End Sub

    Private Sub OutputThreadHandler()
        Dim strLine As String
        '-- this will run forever until the thread is aborted or suspended; this is by design 
        Do While True
            If _blnProcessLaunched Then
                If _p Is Nothing Then Exit Do
                : If _blnCancelRequested Then Exit Do
                strLine = _p.StandardOutput.ReadLine
                If Not strLine Is Nothing Then
                    _OutputBuilder.Append(strLine)
                    _OutputBuilder.Append(Environment.NewLine)
                    : RaiseEvent OutputLine(strLine)
                Else
                    '-- suspend 
                    Thread.Sleep(0)
                End If
            Else
                Thread.Sleep(20)
            End If
        Loop
    End Sub

    Private Sub ErrorThreadHandler()
        Dim strLine As String
        '-- this will run forever until the thread is aborted or suspended; this is by design 
        Do While True
            If _blnProcessLaunched Then
                If _p Is Nothing Then Exit Do
                If _blnCancelRequested Then Exit Do
                strLine = _p.StandardError.ReadLine
                If Not strLine Is Nothing Then
                    _ErrorBuilder.Append(strLine)
                    _ErrorBuilder.Append(Environment.NewLine)
                Else
                    '-- suspend 
                    Thread.Sleep(0)
                End If
            Else
                Thread.Sleep(20)
            End If
        Loop
    End Sub

    Private Sub StartProcess(ByVal strFileName As String, Optional ByVal strArguments As String = "")
        Dim LaunchThread As Thread = Nothing

        _p = New Process
        With _p.StartInfo
            If Not _strWorkingDirectory Is Nothing Then
                .WorkingDirectory = _strWorkingDirectory
            End If
            .FileName = strFileName
            .Arguments = strArguments
            .UseShellExecute = False
            .CreateNoWindow = True
            .RedirectStandardOutput = _blnGetOutput
            .RedirectStandardError = _blnGetError
        End With

        _StartTime = DateTime.Now
        If _blnLaunchInThread Then
            LaunchThread = New Thread(New ThreadStart(AddressOf LaunchThreadHandler))
            LaunchThread.Name = "ShellLaunchThread"
            LaunchThread.Start()
        Else
            _p.Start()
            _blnProcessLaunched = True
        End If
        '-- spawn threads to read in <b style="color: black; background-color: rgb(153, 255, 153);">output</b> and error as they are created 
        If _blnGetOutput Then
            _OutputBuilder = New StringBuilder
            _OutputThread = New Thread(New ThreadStart(AddressOf OutputThreadHandler))
            _OutputThread.Name = "ShellOutputThread"
            _OutputThread.Start()
        End If
        If _blnGetError Then
            _ErrorBuilder = New StringBuilder
            _ErrorThread = New Thread(New ThreadStart(AddressOf ErrorThreadHandler))
            _ErrorThread.Name = "ShellErrorThread"
            _ErrorThread.Start()
        End If

        If LaunchThread Is Nothing Then
            WaitForExit()
        End If
    End Sub

    Private Sub WaitForExit()
        '-- wait for process to exit, or else we time out 
        _blnCancelRequested = False
        Dim intWaitedMs As Integer = 0
        Do While (Not ProcessHasExited()) And (intWaitedMs < _intMaxWaitMs) And (Not _blnCancelRequested)
            Thread.Sleep(_intSleepMs)
            intWaitedMs += _intSleepMs
        Loop

        CloseThreads()

        '-- if we timed out, kill the process 
        If (intWaitedMs >= _intMaxWaitMs) Or _blnCancelRequested Then
            _p.Kill()
            RaiseEvent ExecutionComplete(True)
        Else
            RaiseEvent ExecutionComplete(False)
        End If
    End Sub

    Private Sub CloseThreads()
        If Not _OutputThread Is Nothing Then
            If _OutputThread.IsAlive() Then
                _OutputThread.Abort()
            End If
            _OutputThread = Nothing
        End If
        If Not _ErrorThread Is Nothing Then
            If _ErrorThread.IsAlive() Then
                _ErrorThread.Abort()
            End If
            _ErrorThread = Nothing
        End If
    End Sub
#Region "  Destructor"

    Public Overloads Sub Dispose() Implements System.IDisposable.Dispose
        Dispose(False)
        GC.SuppressFinalize(Me)
    End Sub

    Protected Overridable Overloads Sub Dispose(ByVal IsFinalizer As Boolean)
        If Not _blnDisposed Then
            If IsFinalizer Then
            End If
            If Not _p Is Nothing Then
                _p.Close()
                _p = Nothing
            End If
            CloseThreads()
        End If
        _blnDisposed = True
    End Sub

    Protected Overrides Sub Finalize()
        Dispose(True)
    End Sub
#End Region

End Class